package com.cortex.pineapple.view;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.PixelFormat;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
import android.view.ViewGroup;
import android.view.WindowManager.LayoutParams;
import android.view.WindowManager;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.widget.AbsListView;
import android.widget.AbsListView.OnScrollListener;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.BaseAdapter;
import android.widget.FrameLayout;
import android.widget.GridView;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.Toast;

import com.cortex.pineapple.R;
import com.cortex.pineapple.adapters.ImageAdapter;
import com.cortex.pineapple.adapters.LinkAdapter;
import com.cortex.pineapple.adapters.NewsAdapter;
import com.cortex.pineapple.adapters.VideoAdapter;
import com.cortex.pineapple.adapters.WebAdapter;
import com.cortex.pineapple.fetch.RequestData.CATEGORY_FILTER_TYPE;
import com.cortex.pineapple.fetch.RequestData.SOURCE_TYPE;
import com.cortex.pineapple.fetch.ResponseData;
import com.cortex.pineapple.listener.DragDropView;
import com.cortex.pineapple.listener.DragDropView.OnStateChangedListener;
import com.cortext.pineapple.link.ImageLink;
import com.cortext.pineapple.link.Link;
import com.cortext.pineapple.link.NewsLink;
import com.cortext.pineapple.link.VideoLink;
import com.cortext.pineapple.link.WebLink;

public class ResultsView extends LinearLayout 
implements OnScrollListener,OnItemClickListener, OnTouchListener{

	private ListView listWeb,listNews;
	private GridView listImage,listVideo;
	private List<AbsListView> listResults;
	private RelativeLayout containerWebResults,containerNewsResults;
	private RelativeLayout containerImageResults,containerVideoResults;
	private List<RelativeLayout> containerListResults;
	private FrameLayout titleWebResults,titleNewsResults;
	private FrameLayout titleImageResults,titleVideoResults;
	private FrameLayout[] titleListResults = new FrameLayout[4];
	private View lineImage,lineVideo,lineNews;
	private View[] lines = new View[3];
	private OnSelectedLinkListener onSelectedLinkListener;
	private OnFinishedScrollResultsListener onFinishedScrollListnener;
	private int totalWebResults = 0,totalImageResults = 0,totalVideoResults = 0,totalNewsResults = 0;
	private boolean isScrolling = false;
	private Animation rightIn,rightOut,leftIn,leftOut;
	private CATEGORY_FILTER_TYPE lastCategoryFilterShow;
	private DragDropView dragDropview;

	public ResultsView(Context context) {
		super(context);
		init();
	}
	public ResultsView(Context context, AttributeSet attrs) {
		super(context, attrs);
		init();
	}
	public ResultsView(Context context, AttributeSet attrs,int style) {
		super(context, attrs,style);
		init();
	}
	private void init(){
		LayoutInflater.from(getContext()).inflate(R.layout.view_results, this);

		listWeb = (ListView)findViewById(R.id.listWeb);
		listImage = (GridView)findViewById(R.id.listImage);
		listVideo = (GridView)findViewById(R.id.listVideo);
		listNews = (ListView)findViewById(R.id.listNews);

		listResults = new ArrayList<AbsListView>();
		listResults.add(listWeb);
		listResults.add(listImage);
		listResults.add(listVideo);
		listResults.add(listNews);

		containerWebResults = (RelativeLayout)findViewById(R.id.containerWebResults);
		containerImageResults = (RelativeLayout)findViewById(R.id.containerImageResults);
		containerVideoResults = (RelativeLayout)findViewById(R.id.containerVideoResults);
		containerNewsResults = (RelativeLayout)findViewById(R.id.containerNewsResults);


		containerListResults = new ArrayList<RelativeLayout>();
		containerListResults.add(containerWebResults);
		containerListResults.add(containerImageResults);
		containerListResults.add(containerVideoResults);
		containerListResults.add(containerNewsResults);


		titleWebResults = (FrameLayout)findViewById(R.id.titleWebResults);
		titleImageResults = (FrameLayout)findViewById(R.id.titleImageResults);
		titleVideoResults = (FrameLayout)findViewById(R.id.titleVideoResults);
		titleNewsResults = (FrameLayout)findViewById(R.id.titleNewsResults);

		titleListResults[0] = titleWebResults;
		titleListResults[1] = titleImageResults;
		titleListResults[2] = titleVideoResults;
		titleListResults[3] = titleNewsResults;

		lineImage = findViewById(R.id.lineImage);
		lineVideo = findViewById(R.id.lineVideo);
		lineNews = findViewById(R.id.lineNews);

		lines[0] = lineImage;
		lines[1] = lineVideo;
		lines[2] = lineNews;

		rightIn = AnimationUtils.loadAnimation(getContext(), R.anim.push_right_and_fade_in);
		rightOut = AnimationUtils.loadAnimation(getContext(), R.anim.push_right_and_fade_out);
		leftIn = AnimationUtils.loadAnimation(getContext(), R.anim.push_left_and_fade_in);
		leftOut = AnimationUtils.loadAnimation(getContext(), R.anim.push_left_and_fade_out);

		dragDropview = new DragDropView();

		initListeners();
	}
	private void initListeners(){
		for (AbsListView listView : listResults) {
			listView.setOnItemClickListener(this);
			listView.setOnScrollListener(this);
		}
		for (int i = 0; i < titleListResults.length; i++) {
			titleListResults[i].setOnTouchListener(this);
		}
		dragDropview.setOnStateChangedListener(new OnStateChangedListener() {

			@Override
			public void stopDragging(View dragView,int x, int y) {
				ViewGroup parentViewDrag = (ViewGroup) dragView.getParent();
				if(parentViewDrag != null){
					int indexNext = getIndexChildByLocation(x, y);
					dragView.setVisibility(VISIBLE);
					parentViewDrag.removeView(dragView);
					parentViewDrag.addView(dragView, indexNext);
				}
			}

			@Override
			public void startDragging(View dragView,int x, int y) {
				dragView.setVisibility(INVISIBLE);
			}

			@Override
			public void moveDragging(View dragView,int x, int y) {
				ViewGroup parentViewDrag = (ViewGroup) dragView.getParent();

				int currentIndex = parentViewDrag.indexOfChild(parentViewDrag);
				int nextIndex = getIndexChildByLocation(x, y);
				if(nextIndex != -1){
					View nextView = parentViewDrag.getChildAt(nextIndex);
					Rect currentRect = new Rect();
					Rect nextRect = new Rect();

					dragView.getLocalVisibleRect(currentRect);
					nextView.getLocalVisibleRect(nextRect);
					if(currentIndex != nextIndex){
						nextView.layout(currentRect.left, currentRect.top, 
								currentRect.right, currentRect.bottom);
						//						dragView.layout(nextRect.left, nextRect.top, 
						//								nextRect.right, nextRect.bottom);
					}
				}
			}
		});
	}
	private int getIndexChildByLocation(int x,int y){
		int centerPositionXChild,left,right;
		Rect rect = new Rect();
		ViewGroup containerResults = (ViewGroup)getChildAt(0);
		for (int i = 0; i < containerResults.getChildCount(); i++) {
			View child = containerResults.getChildAt(i);
			child.getLocalVisibleRect(rect);
			left = child.getLeft();
			right = child.getRight();
			if(x > left && x < right){
				centerPositionXChild = child.getLeft() + child.getWidth()/2;
				if(x>centerPositionXChild && i == containerResults.getChildCount()-1){
					return i;
				}
				else if(x<centerPositionXChild && i==0){
					return 0;
				}
				return x>centerPositionXChild?i+1:i-1;
			}
		}
		return -1;
	}
	public void setOnSelectedLinkListener(OnSelectedLinkListener onSelectedLinkListener) {
		this.onSelectedLinkListener = onSelectedLinkListener;
	}
	public void setOnFinishedScrollListnener(OnFinishedScrollResultsListener onFinishedScrollListnener) {
		this.onFinishedScrollListnener = onFinishedScrollListnener;
	}

	public int getTotalWebResults() {
		return totalWebResults;
	}
	public int getTotalImageResults() {
		return totalImageResults;
	}
	public int getTotalVideoResults() {
		return totalVideoResults;
	}
	public int getTotalNewsResults() {
		return totalNewsResults;
	}

	public int getNumberSourcesVisible(){
		int numberSourcesVisible = 0;
		if(containerWebResults.getVisibility() == VISIBLE){
			numberSourcesVisible++;
		}
		if(containerImageResults.getVisibility() == VISIBLE){
			numberSourcesVisible++;
		}
		if(containerVideoResults.getVisibility() == VISIBLE){
			numberSourcesVisible++;
		}
		if(containerNewsResults.getVisibility() == VISIBLE){
			numberSourcesVisible++;
		}
		return numberSourcesVisible;
	}

	public List<WebLink> getWebLinks(){
		if(listWeb.getAdapter() != null){
			return ((LinkAdapter<WebLink>)listWeb.getAdapter()).getLinks();
		}
		return null;
	}
	public List<ImageLink> getImageLinks(){
		if(listImage.getAdapter() != null){
			return ((LinkAdapter<ImageLink>)listImage.getAdapter()).getLinks();
		}
		return null;
	}
	public List<VideoLink> getVideoLinks(){
		if(listVideo.getAdapter() != null){
			return ((LinkAdapter<VideoLink>)listVideo.getAdapter()).getLinks();
		}
		return null;
	}
	public List<NewsLink> getNewsLinks(){
		if(listNews.getAdapter() != null){
			return ((LinkAdapter<NewsLink>)listNews.getAdapter()).getLinks();
		}
		return null;
	}
	public void show(ResponseData response){
		if(response == null || !response.isSuccess()){
			Toast.makeText(getContext(), getResources().getString(R.string.noResults), Toast.LENGTH_LONG).show();
			return;
		}
		buildView(response);
		setVisibility(VISIBLE);
	}
	private void buildView(ResponseData response){
		List<SOURCE_TYPE> sources = response.getSourcesType();

		Animation in = getInAnimation(lastCategoryFilterShow, response.getCategoryFilter());
		Animation out = getOutAnimation(lastCategoryFilterShow, response.getCategoryFilter());
		View viewIn = null;
		for (SOURCE_TYPE source : sources) {
			switch(source){
			case IMAGES:
				updateImageResults(response.getImageLinks());
				viewIn = containerImageResults;
				break;
			case NEWS:
				updateNewsResults(response.getNewsLinks());
				viewIn = containerNewsResults;
				break;
			case VIDEO:
				updateVideoResults(response.getVideoLinks());
				viewIn = containerVideoResults;
				break;
			case WEB:
				updateWebResults(response.getWebLinks());
				viewIn = containerWebResults;
				break;
			default:
				break;
			}
			if(!isScrolling && out != null){
				if(!sources.contains(SOURCE_TYPE.IMAGES)){
					setVisibleViews(false,out, containerImageResults);
				}
				if(!sources.contains(SOURCE_TYPE.NEWS)){
					setVisibleViews(false,out, containerNewsResults);
				}
				if(!sources.contains(SOURCE_TYPE.VIDEO)){
					setVisibleViews(false,out, containerVideoResults);
				}
				if(!sources.contains(SOURCE_TYPE.WEB)){
					setVisibleViews(false,out, containerWebResults);
				}
			}
			if(in != null && viewIn != null){
				setVisibleViews(true,in, viewIn);
			}
			lastCategoryFilterShow = response.getCategoryFilter();
		}
		if(getNumberSourcesVisible() == 1){
			setViewsVisible(GONE,titleListResults);
			setViewsVisible(GONE,lines);
		}
		else{
			setViewsVisible(VISIBLE,titleListResults);
			setViewsVisible(VISIBLE,lines);
		}
		isScrolling = false;
	}
	private Animation getInAnimation(
			CATEGORY_FILTER_TYPE lastCategoreyFilter,CATEGORY_FILTER_TYPE nextCategoryFilter){
		if(lastCategoreyFilter == null){
			return leftIn;
		}
		else if(lastCategoreyFilter.ordinal() < nextCategoryFilter.ordinal()){
			return leftIn;
		}
		else if(lastCategoreyFilter.ordinal() > nextCategoryFilter.ordinal()){
			return rightIn;
		}
		else if(nextCategoryFilter == CATEGORY_FILTER_TYPE.COMPOSITE){
			return leftIn;
		}
		return leftIn;
	}
	private Animation getOutAnimation(
			CATEGORY_FILTER_TYPE lastCategoreyFilter,CATEGORY_FILTER_TYPE nextCategoryFilter){
		if(lastCategoreyFilter == null){
			return rightOut;
		}
		else if(lastCategoreyFilter.ordinal() < nextCategoryFilter.ordinal()){
			return rightOut;
		}
		else if(lastCategoreyFilter.ordinal() > nextCategoryFilter.ordinal()){
			return leftOut;
		}
		else if(nextCategoryFilter == CATEGORY_FILTER_TYPE.COMPOSITE){
			return rightOut;
		}
		return rightOut;
	}
	private void updateWebResults(List<WebLink> links){
		if(links != null){
			WebAdapter webAdapter = (WebAdapter) listWeb.getAdapter();
			if(webAdapter == null){
				webAdapter = new WebAdapter(getContext());
				listWeb.setAdapter(webAdapter);
			}
			webAdapter.addLinks(links);
			totalWebResults = links.size();
		}
	}

	private void updateImageResults(List<ImageLink> links){
		if(links != null){
			ImageAdapter imageAdapter = (ImageAdapter) listImage.getAdapter();
			if(imageAdapter == null){
				imageAdapter = new ImageAdapter(getContext());
				listImage.setAdapter(imageAdapter);
			}
			imageAdapter.addLinks(links);
			totalImageResults = links.size();
		}
	}

	private void updateVideoResults(List<VideoLink> links){
		if(links != null){
			VideoAdapter videoAdapter = (VideoAdapter) listVideo.getAdapter();
			if(videoAdapter == null){
				videoAdapter = new VideoAdapter(getContext());
				listVideo.setAdapter(videoAdapter);
			}
			videoAdapter.addLinks(links);
			totalVideoResults = links.size();
		}
	}

	private void updateNewsResults(List<NewsLink> links){
		if(links != null){
			NewsAdapter newsAdapter = (NewsAdapter) listNews.getAdapter();
			if(newsAdapter == null){
				newsAdapter = new NewsAdapter(getContext());
				listNews.setAdapter(newsAdapter);
			}
			newsAdapter.addLinks(links);
			totalNewsResults = links.size();
		}
	}

	private void setVisibleViews(boolean isVisible,Animation animation,View... views){
		for (int i = 0; i < views.length; i++) {
			View v = views[i];
			if(v.getVisibility() == GONE && isVisible){
				v.startAnimation(animation);
			}
			else if(v.getVisibility() == VISIBLE && !isVisible){
				v.startAnimation(animation);
			}
			v.setVisibility(isVisible?VISIBLE:GONE);
		}

	}
	private void setViewsVisible(int visible,View... views){

		for (int i = 0; i < views.length; i++) {
			views[i].setVisibility(visible);
		}
	}
	@Override
	public void onScroll(AbsListView view, int firstVisibleItem,
			int visibleItemCount, int totalItemCount) {

	}
	@Override
	public void onScrollStateChanged(AbsListView view, int scrollState) {
		if(scrollState == SCROLL_STATE_IDLE){
			BaseAdapter adapter = (BaseAdapter) view.getAdapter();
			if((view.getLastVisiblePosition() == adapter.getCount()-1)){
				if(onFinishedScrollListnener != null){
					List<SOURCE_TYPE> sources = new ArrayList<SOURCE_TYPE>();
					CATEGORY_FILTER_TYPE filterType = CATEGORY_FILTER_TYPE.WEB;
					if(view.getId() == listWeb.getId()){
						sources.add(SOURCE_TYPE.WEB);
						filterType = CATEGORY_FILTER_TYPE.WEB;
					}
					else if(view.getId() == listImage.getId()){
						sources.add(SOURCE_TYPE.IMAGES);
						filterType = CATEGORY_FILTER_TYPE.IMAGES;
					}
					else if(view.getId() == listVideo.getId()){
						sources.add(SOURCE_TYPE.VIDEO);
						filterType = CATEGORY_FILTER_TYPE.VIDEO;
					}
					else if(view.getId() == listNews.getId()){
						sources.add(SOURCE_TYPE.NEWS);
						filterType = CATEGORY_FILTER_TYPE.NEWS;
					}
					isScrolling = true;
					onFinishedScrollListnener.finishedScroll(adapter.getCount(), filterType,sources);
				}
			}
		}
	}

	@Override
	public void onItemClick(AdapterView<?> adapterView, View view, int position, long id) {
		if(onSelectedLinkListener != null){
			List<Link> list = new ArrayList<Link>();
			BaseAdapter adapter = (BaseAdapter)adapterView.getAdapter();
			for (int i = 0; i < adapter.getCount(); i++) {
				list.add((Link) adapter.getItem(i));
			}
			onSelectedLinkListener.selectedLink(list,(Link) adapter.getItem(position));
		}
	}
	@Override
	public void setEnabled(boolean enabled) {
		super.setEnabled(enabled);
		for (AbsListView listView : listResults) {
			listView.setEnabled(enabled);
		}
	}
	public void clear(){
		for (AbsListView listView : listResults) {
			if(listView.getAdapter() != null){
				((LinkAdapter<? extends Link>)listView.getAdapter()).clear();
			}
		}
	}

	@Override
	public boolean onTouch(View v, MotionEvent event) {
		if(v.getId() == titleWebResults.getId()){
			dragDropview.setDragView(containerWebResults);
		}
		else if(v.getId() == titleImageResults.getId()){
			dragDropview.setDragView(containerImageResults);
		}
		else if(v.getId() == titleVideoResults.getId()){
			dragDropview.setDragView(containerVideoResults);
		}
		else if(v.getId() == titleNewsResults.getId()){
			dragDropview.setDragView(containerNewsResults);
		}
		return false;
	} 
	public interface OnSelectedLinkListener{
		void selectedLink(List<Link> links,Link link);
	}
	public interface OnFinishedScrollResultsListener{
		void finishedScroll(int totalResults,CATEGORY_FILTER_TYPE filter,List<SOURCE_TYPE> sources);
	}
}
